package com.libgdxbar.pvzlikegame.systems.render;

import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.libgdxbar.pvzlikegame.entities.Entity;
import com.libgdxbar.pvzlikegame.entities.EntitySystem;

import org.libgdxbar.projects.interfaces.renderer.IBatchRender;
import org.libgdxbar.projects.interfaces.renderer.IRender;
import org.libgdxbar.projects.interfaces.renderer.IShapeRender;

import java.util.function.Supplier;

public class RenderSystem extends EntitySystem implements Disposable {

	private Supplier<Camera> cameraSupplier;

	public RenderSystem(Supplier<Camera> cameraSupplier) {
		if (cameraSupplier.get() == null) {
			throw new RuntimeException("未设置相机.");
		}
		this.cameraSupplier = cameraSupplier;
	}

	private final Array<Job> renderableEntities = new Array<>();
	// 用于渲染的Batch和ShapeRenderer
	public Batch batch = new SpriteBatch();
	public ShapeRenderer shapeRenderer = new ShapeRenderer() {{
		setAutoShapeType(true);
	}};
	// 渲染代理对象，用于批量渲染和形状渲染
	private BatchRenderAgent batchRenderAgent = new BatchRenderAgent(batch);
	private ShapeRenderAgent shapeRenderAgent = new ShapeRenderAgent(shapeRenderer);

	@Override
	public void onEntityAdded(Entity entity) {
		if (entity instanceof IRender) {
			IRender renderer = (IRender) entity;
			if (entity instanceof IShapeRender) {
				this.renderableEntities.add(new Job(renderer, shapeRenderAgent));
			}
			if (entity instanceof IBatchRender) {
				this.renderableEntities.add(new Job(renderer, batchRenderAgent));
			}
		}
	}

	@Override
	public void onEntityRemoved(Entity entity) {
		if (entity instanceof IRender) {
			IRender renderer = (IRender) entity;
			for (int i = 0; i < this.renderableEntities.size; i++) {
				Job job = this.renderableEntities.get(i);
				if (job.renderer != renderer) {
					continue;
				}
				this.renderableEntities.removeIndex(i);
				break;
			}
		}
	}

	@Override
	public void run(float delta) {
		render(cameraSupplier.get());
	}

	/**
	 * 渲染所有实体对象
	 *
	 * @param camera 渲染使用的摄像机
	 */
	public void render(Camera camera) {
		// 按照Z轴值对可渲染作业进行排序，确保渲染顺序正确
		renderableEntities.sort((o1, o2) -> Float.compare(o1.renderer.z(), o2.renderer.z()));

		// 当前活跃的渲染代理
		IRenderAgent activeAgent = null;

		// 遍历所有可渲染作业
		for (Job job : renderableEntities) {
			final IRenderAgent agent = job.agent;

			// 如果当前作业的渲染代理与活跃代理不同
			if (agent != activeAgent) {
				// 如果有活跃代理，结束其渲染
				if (activeAgent != null) {
					activeAgent.end();
				}

				// 更新活跃代理为当前作业的渲染代理
				activeAgent = agent;

				// 设置渲染代理的视图相机
				activeAgent.setView(camera);

				// 开始渲染
				activeAgent.begin();
			}

			// 使用当前活跃代理渲染当前作业
			agent.render(job.renderer);
		}

		// 如果有活跃代理，结束其渲染
		if (activeAgent != null) {
			activeAgent.end();
		}
	}

	@Override
	public void dispose() {
		batch.dispose();
		shapeRenderer.dispose();
	}
}
